package com.lincoln.service;

import com.lincoln.entity.todo.DbTodo;
import com.lincoln.entity.todo.TodoStatusEnum;
import com.lincoln.repository.TodoRepository;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class TodoService extends BaseService<DbTodo, TodoRepository> {

    /**
     * 建立分页排序请求
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public PageRequest buildPageRequest(int pageNo, int pageSize, Sort.Order... orders) {
        Sort sort = Sort.by(orders);
        return PageRequest.of(pageNo, pageSize, sort);
    }

    @Override
    public Predicate createPredicate(Root<DbTodo> root, CriteriaBuilder cb, Map<String, Object> params) {
        Predicate result = cb.and();
        if (params.get("userId") != null) {
            Predicate p = cb.equal(root.get("user").get("id").as(Long.class), params.get("userId"));
            result = cb.and(result, p);
        }
        if (params.get("qq") != null) {
            Predicate p = cb.equal(root.get("user").get("qq").as(String.class), params.get("qq"));
            result = cb.and(result, p);
        }
        if (params.get("groupId") != null) {
            Predicate p = cb.equal(root.get("group").get("id").as(Long.class), params.get("groupId"));
            result = cb.and(result, p);
        }
        if (params.get("startTimeGt") != null) {
            Predicate p = cb.greaterThan(root.get("startTime").as(Date.class), (Date) params.get("startTimeGt"));
            result = cb.and(result, p);
        }
        if (params.get("startTimeGe") != null) {
            Predicate p = cb.greaterThanOrEqualTo(root.get("startTime").as(Date.class), (Date) params.get("startTimeGe"));
            result = cb.and(result, p);
        }
        if (params.get("startTimeLt") != null) {
            Predicate p = cb.lessThan(root.get("startTime").as(Date.class), (Date) params.get("startTimeLt"));
            result = cb.and(result, p);
        }
        if (params.get("startTimeLe") != null) {
            Predicate p = cb.lessThanOrEqualTo(root.get("startTime").as(Date.class), (Date) params.get("startTimeLe"));
            result = cb.and(result, p);
        }
        if (params.get("endTimeGt") != null) {
            Predicate p = cb.greaterThan(root.get("endTime").as(Date.class), (Date) params.get("endTimeGt"));
            result = cb.and(result, p);
        }
        if (params.get("endTimeGe") != null) {
            Predicate p = cb.greaterThanOrEqualTo(root.get("endTime").as(Date.class), (Date) params.get("endTimeGe"));
            result = cb.and(result, p);
        }
        if (params.get("endTimeLt") != null) {
            Predicate p = cb.lessThan(root.get("endTime").as(Date.class), (Date) params.get("endTimeLt"));
            result = cb.and(result, p);
        }
        if (params.get("endTimeLe") != null) {
            Predicate p = cb.lessThanOrEqualTo(root.get("endTime").as(Date.class), (Date) params.get("endTimeLe"));
            result = cb.and(result, p);
        }
        if (params.get("numberGt") != null) {
            Predicate p = cb.greaterThan(root.get("number").as(Integer.class), (Integer) params.get("numberGt"));
            result = cb.and(result, p);
        }
        if (params.get("status") != null) {
            Predicate p = cb.equal(root.get("status").as(TodoStatusEnum.class), params.get("status"));
            result = cb.and(result, p);
        }
        if (params.get("statusNe") != null) {
            Predicate p = cb.notEqual(root.get("status").as(TodoStatusEnum.class), params.get("statusNe"));
            result = cb.and(result, p);
        }
        return result;
    }

    /**
     * 查找一下未开始且还有剩余人数的活动
     * @return
     */
    public List<DbTodo> findWaitTodo(){
        Map<String,Object> params = new HashMap<>();
        params.put("statusNe", TodoStatusEnum.END);
        params.put("numberGt",0);
        params.put("endTimeGe",new Date());
        return findList(params);
    }

    /**
     * 查找一下未开始且还有剩余人数的活动
     * @return
     */
    public List<DbTodo> findWaitTodo(long groupId){
        Map<String,Object> params = new HashMap<>();
        params.put("groupId", groupId);
        params.put("status", TodoStatusEnum.WATI);
        params.put("numberGt",0);
        params.put("endTimeGe",new Date());
        return findList(params);
    }

    /**
     * 查找某个用户的未开始且还有剩余人数的活动
     * @return
     */
    public List<DbTodo> findWaitTodo(String qq,long groupId){
        Map<String,Object> params = new HashMap<>();
        params.put("qq", qq);
        params.put("groupId", groupId);
        params.put("status", TodoStatusEnum.WATI);
        params.put("numberGt",0);
        params.put("endTimeGe",new Date());
        return findList(params);
    }
}
